package com.dingreading.cloud.admin.util;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class RC4Util {

    public static String decry_RC4(char[] data, String key) {
        if (data == null || key == null) {
            return null;
        }
        return asString(RC4Base(data, key.toCharArray()));
    }


    public static String decry_RC4(String data, String key) {
        if (data == null || key == null) {
            return null;
        }
        return new String(RC4Base(HexString2Bytes(data), key.toCharArray()));
    }


    public static char[] encry_RC4_byte(String data, String key) {
        if (data == null || key == null) {
            return null;
        }
        char[] b_data = data.toCharArray();
        return RC4Base(b_data, key.toCharArray());
    }


    public static String encry_RC4_string(String data, String key) {
        if (key == null || key.equals("")) {
            key = "passwordkey";
        }
        if (data == null || key == null) {
            return null;
        }
        return toHexString(asString(encry_RC4_byte(data, key)));
    }


    private static String asString(char[] buf) {
        StringBuffer strbuf = new StringBuffer(buf.length);
        for (int i = 0; i < buf.length; i++) {
            strbuf.append(buf[i]);
        }
        return strbuf.toString();
    }


    private static char[] initKey(char[] aKey) {
        char[] state = new char[256];

        for (int i = 0; i < 256; i++) {
            state[i] = (char) i;
        }
        int index1 = 0;
        int index2 = 0;
        if (aKey == null || aKey.length == 0) {
            return null;
        }
        for (int i = 0; i < 256; i++) {
            index2 = ((aKey[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff;
            char tmp = state[i];
            state[i] = state[index2];
            state[index2] = tmp;
            index1 = (index1 + 1) % aKey.length;
        }
        return state;
    }

    private static String toHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = s.charAt(i);
            String s4 = Integer.toHexString(ch & 0xFF);
            if (s4.length() == 1) {
                s4 = '0' + s4;
            }
            str = str + s4;
        }
        return str;
    }


    private static char[] HexString2Bytes(String src) {
        int size = src.length();
        char[] ret = new char[size / 2];
        char[] tmp = src.toCharArray();
        for (int i = 0; i < size / 2; i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    private static char uniteBytes(char src0, char src1) {
        char _b0 = (char) Byte.decode("0x" + src0)
                .byteValue();
        _b0 = (char) (_b0 << 4);
        char _b1 = (char) Byte.decode("0x" + src1)
                .byteValue();
        char ret = (char) (_b0 ^ _b1);
        return ret;
    }

    private static char[] RC4Base(char[] input, char[] mKkey) {
        int x = 0;
        int y = 0;
        char[] key = initKey(mKkey);
        int xorIndex;
        char[] result = new char[input.length];

        for (int i = 0; i < input.length; i++) {
            x = (x + 1) & 0xff;
            y = ((key[x] & 0xff) + y) & 0xff;
            char tmp = key[x];
            key[x] = key[y];
            key[y] = tmp;
            xorIndex = ((key[x] & 0xff) + (key[y] & 0xff)) & 0xff;
            result[i] = (char) (input[i] ^ key[xorIndex]);
        }
        return result;
    }

    public static byte[] getBytes(char[] chars) {
        Charset cs = StandardCharsets.ISO_8859_1;
        CharBuffer cb = CharBuffer.allocate(chars.length);
        cb.put(chars);
        cb.flip();
        ByteBuffer bb = cs.encode(cb);

        return bb.array();

    }

//    public static void main(String[] args) throws UnsupportedEncodingException
//    {
//        //加密
//        String inputStr = "111111";
//        String key = "passwordkey";
//        String aa = RC4Util.encry_RC4_string(inputStr, key);
//        System.out.println(aa);
//
//        //解密
//        String a = RC4Util.decry_RC4("3821f50e136a","passwordkey");
//        System.out.println(a);
//    }
}